package cn.juc;

import lombok.extern.slf4j.Slf4j;

import java.util.concurrent.locks.StampedLock;

/**
 * stamp的测试
 */
@Slf4j
public class StampLockTest {
    public static void main(String[] args) {
        DataStamp dataStamp=new DataStamp(20);
        new Thread(()->{
            try {
                log.info("读出数据{}",dataStamp.read());
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        },"t1").start();
        new Thread(()->{
           // log.info("读出数据{}",dataStamp.read());
            dataStamp.write(40);
        },"t2").start();
    }
}
@Slf4j
class DataStamp{
    private int data;
    private final StampedLock lock=new StampedLock();

    public DataStamp(int data) {
        this.data = data;
    }

    public int read() throws InterruptedException {
        long stamp = lock.tryOptimisticRead();
        log.info("read stamp {}",stamp);
        //Thread.sleep(2000);
        if (lock.validate(stamp)){
            log.info("未修改，直接返回");
            return this.data;
        }
        try {
            log.info("数据修改，锁升级");
            //lock.readLock();
            stamp=lock.readLock();
            //Thread.sleep(2000);
            log.info("成功读取 {}",stamp);
            return data;
        }finally {
           lock.unlockRead(stamp);
            //return data;
        }
    }
    public void write(int data){
        long stamp = lock.writeLock();
        log.info("write stamp {}",stamp);
        try {
            //lock.writeLock();
            Thread.sleep(2000);
            log.info("成功写入");
            this.data=data;
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        finally {
            log.info("write unlock");
            lock.unlockWrite(stamp);
        }
    }
}
